import QtQuick
import QtQuick.Controls
import Qt5Compat.GraphicalEffects


Item {
    id: root

    property string imgSource: "../resources/images/1.jpg"
    property color backgroundColor: "transparent"
    property int imgFillMode: Image.Stretch // 图片的填充方式
    property bool blur: true    // 针对 PreserveAspectFit 进行模糊处理
    property int radius: 0
    smooth: true
    width: 600
    height: 400

    Rectangle {
        id: mask
        anchors.fill: parent
        radius: root.radius
        visible: false
    }

    Image {
        id: image
        source: root.imgSource
        visible: false
        onStatusChanged: {
            if (status === Image.Ready) {
                canvas.ready = true
                canvas.requestPaint()
            }
        }
    }

    Canvas {
        id: canvas
        anchors.fill: parent
        smooth: root.smooth
        property bool ready: false

        Loader{
            anchors.fill:parent
            z: -1
            id: loader
        }

        onPaint: {
            if (!(ready && image.status === Image.Ready)) return;
            var ctx = getContext('2d');

            ctx.fillStyle = root.backgroundColor;
            ctx.fillRect(0, 0, root.width, root.height);

            if(root.imgFillMode === Image.Stretch){
                stretchImage(ctx);
            }
            else if(root.imgFillMode === Image.PreserveAspectFit){
                preserveAspectFitImage(ctx);
            }
            else if(root.imgFillMode === Image.PreserveAspectCrop){
                preserveAspectCropImage(ctx);
            }
        }

        layer.enabled: true
        layer.effect: OpacityMask {
            maskSource: mask
        }

        function stretchImage(ctx){
            ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
        }

        function preserveAspectFitImage(ctx){
            var imgRatio = image.width / image.height;
            var canvasRatio = canvas.width / canvas.height;
            var dw, dh, dy, dx;

            if (imgRatio > canvasRatio) { // 图片长
                dw = canvas.width;
                dh = dw / imgRatio;
                dx = 0;
                dy = (canvas.height - dh) / 2
            }
            else{
                dh = canvas.height;
                dw = canvas.height * imgRatio;
                dy = 0;
                dx = (canvas.width - dw) / 2;
            }

            if (root.blur) {
                loader.setSource("BlurImg.qml", {
                                     "imgSource": root.imgSource
                                 });
            }

            ctx.drawImage(image, 0, 0, image.width, image.height, dx, dy, dw, dh);
        }

        function preserveAspectCropImage(ctx){
            var imgRatio = image.width / image.height;
            var canvasRatio = canvas.width / canvas.height;
            var sx, sy, sw, sh;
            var imgw, imgh;

            if (imgRatio > canvasRatio) {
                sh = image.height;
                sw = sh * canvasRatio;
                sx = (image.width - sw) / 2;
                sy = 0;
            } else {
                sw = image.width;
                sh = sw / canvasRatio;
                sx = 0;
                sy = (image.height - sh) / 2;
            }

            ctx.drawImage(image, sx, sy, sw, sh, 0, 0, canvas.width, canvas.height);
        }
    }

    onWidthChanged: canvas.requestPaint()
    onHeightChanged: canvas.requestPaint()
}

